package com.touch.jgloo.owt;
import com.sun.opengl.util.texture.Texture;
import com.touch.jgloo.core.JGLQuad;
import com.touch.graphics.Renderable;
import java.util.Vector;
/**
 * Animation data. Contains which frame is animating.
 * @see com/touch/Licence
 * @version 10.2.19
 * @since r471
 */
public class JGLAnimation implements Renderable, Cloneable
{
	//list of frames used for animation; uses Texture for frame data
	private Vector<Texture> frame = new Vector<Texture>();
	//JGLObject used to draw the frame.
	private JGLQuad animQuad;
	//index of the currently executing frame
	private int frameIndex;
	//milliseconds the frame is shown. Recommended is 300. 
	private long frameDuration = 300;
	//System Time for the last animated frame. Used to determine if another frame should be used.
	private long lastFrameTime;
	//True: animating; False: stationary frame.
	private boolean animating;
	//Size of the animation
	private int width, height;
	/**
	 * Builds a new Animation using width and height information.
	 * @param width Width of the Animation
	 * @param height Height of the Animation
	 * @since r471
	 */
	public JGLAnimation(final int width, final int height)
	{		
		//set the width
		this.width = width;
		//set the height
		this.height = height;
		//create the JGLQuad.
		this.animQuad = new JGLQuad(width, height);
		//set the last frame's time as the current time.
		this.lastFrameTime = System.currentTimeMillis();
	}
	/**
	 * Sets the length of time a frame is shown.
	 * @param ms Milliseconds that the frame is shown.
	 * @since r471 
	 */
	public void setFrameDuration(final int ms)
	{
		//update the frame value.
		this.frameDuration = ms;
	}
	/**
	 * Sets the frame's index. The number represents which frame is being used.
	 * @param frameIndex Integer representing the frame's position.
	 * @since r471
	 * @deprecated It is not recommended to use this method because a frame is only visible for a short duration.
	 */
	public void setFrameIndex(final int frameIndex)
	{
		//update the frame index
		this.frameIndex = frameIndex;
	}
	/**
	 * Sets whether the animation is animating.
	 * @param bAnimating True: animation is animating; False: animation is not animating.
	 * @since r471
	 */
	public void setIsAnimating(final boolean bAnimating)
	{
		//update the animation status
		this.animating = bAnimating;
	}
	/**
	 * Returns whether the animation is animating
	 * @return True: animation is animated; False: animation is not animating.
	 */
	public boolean isAnimating()
	{
		//return the animating status
		return this.animating;
	}
	@Override
	public void render()
	{					
		//determine whether the animation is ready to animate
		if(System.currentTimeMillis() > this.lastFrameTime + this.frameDuration)
		{
			//only animate if it is ready
			if(this.isAnimating())
			{	
				//update the frame index
				this.frameIndex++;
				//check if the frame is < the current frame
				if(this.frameIndex == this.frame.size())	
					//reset the frame index
					this.frameIndex = 0;					
										
				this.lastFrameTime = System.currentTimeMillis();				
			}			
			else
				frameIndex = 0;
		}
		this.animQuad.setTexture(this.frame.elementAt(this.frameIndex));
		this.animQuad.render();
	}
	public void addFrame(Texture frame)
	{
		this.frame.add(frame);
	}
	public void setFrame(int frameIndex, Texture frame)
	{
		this.frame.set(frameIndex, frame);
	}
	public Texture getFrame(int frameIndex)
	{
		return this.frame.get(frameIndex);
	}
	public void reset()
	{
		this.frameIndex = 0;
		this.lastFrameTime = System.currentTimeMillis();
	}
	public JGLAnimation clone()
	{
		JGLAnimation clone = new JGLAnimation(this.width, this.height);
		clone.frame = this.frame;
		clone.animQuad = this.animQuad;
		clone.frameDuration = this.frameDuration;
		return clone; 
	}
	public int getWidth()
	{
		return this.width;
	}
	public int getHeight()
	{
		return this.height;
	}
}
